﻿using DJLang;
using System.Collections.Generic;
using System.Linq;
using System.Net;

namespace BlockOS.Client.Res
{
    public class ServerList
    {
        private static readonly string FILE_NAME = "servers.dj";

        public readonly Dictionary<string, IPEndPoint> serverEntries = new();

        public string Src => $"[{string.Join(' ', serverEntries.Select(entry => $"[\"{entry.Key}\" (ip! {entry.Value.Address} {entry.Value.Port})]"))}]";

        public ServerList(AppFiles files)
        {
            if (files.Exists(FILE_NAME))
            {
                using var reader = new DJReader(files.ReadText(FILE_NAME));
                DJEnv env = new();
                env.PutLibrary(typeof(ServerListLoadLib));

                var list = reader.EvaluateToEnd(env) as DJList;

                while (list != null && list.Count > 0)
                {
                    var entry = list.PopAs<DJList>();
                    var name = entry.PopManaged<string>();
                    var ep = entry.Pop().Evaluate(env).GetManaged<IPEndPoint>();

                    serverEntries.Add(name, ep);
                }
            }
        }

        public IPEndPoint GetSever(string name)
        {
            return serverEntries[name];
        }

        public void AddServer(string name, IPEndPoint ep)
        {
            serverEntries.Add(name, ep);
        }

        public void SetServer(string name, IPEndPoint ep)
        {
            serverEntries[name] = ep;
        }

        public void Save(AppFiles files)
        {
            files.SaveText(FILE_NAME, Src);
        }

        public static class ServerListLoadLib
        {
            [DJMacro("ip")]
            public static IDJValue IPEntry(DJEnv _, DJSeq args)
            {
                var ipaddr = args.PopAs<DJSymbol>().name;
                var port = args.PopValue<int>();

                return new DJRef<IPEndPoint>(new IPEndPoint(IPAddress.Parse(ipaddr), port));
            }
        }
    }
}
